GM.Name 	= "RPG:Deathmatch" 
GM.Author 	= "Admiral Ironbuns" 
GM.Email 	= "devin.j.conner@gmail.com" 
GM.Website 	= "http://facepunch.com/member.php?u=107415"

game.AddParticles("particles/blackbetty.pcf")
PrecacheParticleSystem("blood_hands_instacast")
PrecacheParticleSystem("blood_hands")
PrecacheParticleSystem("blood_glow")
PrecacheParticleSystem("blood_erupt_constant")
PrecacheParticleSystem("blood_erupt")
PrecacheParticleSystem("bombtrail")
PrecacheParticleSystem("interactible")
PrecacheParticleSystem("autoshot")
PrecacheParticleSystem("explosivepunch")
PrecacheParticleSystem("frostshot")
PrecacheParticleSystem("pummel_hit")
PrecacheParticleSystem("fire_hands_instacast")
PrecacheParticleSystem("frost_hands_instacast")
PrecacheParticleSystem("light_hands_instacast")
PrecacheParticleSystem("fire_hands")
PrecacheParticleSystem("fire_glow")
PrecacheParticleSystem("frost_hands")
PrecacheParticleSystem("light_hands")
PrecacheParticleSystem("impact_firebig")
PrecacheParticleSystem("impact_light_heal")
PrecacheParticleSystem("impact_light_damage")
PrecacheParticleSystem("impact_firesmall")
PrecacheParticleSystem("impact_frostbig")
PrecacheParticleSystem("impact_frostsmall")
PrecacheParticleSystem("quick_strike")
PrecacheParticleSystem("slam")
PrecacheParticleSystem("player_blood")
PrecacheParticleSystem("impact_hit")
PrecacheParticleSystem("whirlwind")
PrecacheParticleSystem("bomb_explosion")
PrecacheParticleSystem("thunder_clap")
PrecacheParticleSystem("thunderclap_hit")
PrecacheParticleSystem("fireshot")
PrecacheParticleSystem("fireshot_trail")
PrecacheParticleSystem("aimedshot")
PrecacheParticleSystem("snipe")
PrecacheParticleSystem("lavashot")
PrecacheParticleSystem("bindingshot")
PrecacheParticleSystem("poisonshot_hit")
PrecacheParticleSystem("explosivearrow")
PrecacheParticleSystem("explosivearrow_hit")
PrecacheParticleSystem("netshot")
PrecacheParticleSystem("mutilate")
PrecacheParticleSystem("slash")
PrecacheParticleSystem("avoidancetactics")
PrecacheParticleSystem("sprint")
PrecacheParticleSystem("shadowstalk")
PrecacheParticleSystem("execute")
PrecacheParticleSystem("shadowstep")
PrecacheParticleSystem("backstab_hit")
PrecacheParticleSystem("combustion_hit")
PrecacheParticleSystem("burning")
PrecacheParticleSystem("burning_long")

if SERVER then
	util.AddNetworkString( "ChooseSpellUpgrade" )
	util.AddNetworkString( "SendPlayerResource" )
	util.AddNetworkString( "ReceivePlayerResources" )
	util.AddNetworkString( "ReceiveAllPlayerResources" )
	util.AddNetworkString( "SendPlayerResource" )
	util.AddNetworkString( "GreenVictory" )
	util.AddNetworkString( "YellowVictory" )
	util.AddNetworkString( "CancelPlayerCast" )
	util.AddNetworkString( "UpdatePlayerPresets" )
	util.AddNetworkString( "ShowPresetMenu" )
	util.AddNetworkString( "ShowMatchMakingMenu" )
	util.AddNetworkString( "RetrieveMatchData" )
	util.AddNetworkString( "SendMatchData" )
	util.AddNetworkString( "RetrievePlayerInventory" )
	util.AddNetworkString( "RetrievePlayerInventory2" )
	util.AddNetworkString( "SendPlayerInventory" )
	util.AddNetworkString( "SendPlayerInventory2" )
	util.AddNetworkString( "ReceiveGameType" )
	util.AddNetworkString( "SendGameType" )
	util.AddNetworkString( "ChangePlayerSpells" )
	util.AddNetworkString( "SendSelfMaxHealth" )
	util.AddNetworkString( "ChangePlayerSpells" )
	util.AddNetworkString( "SpellCast" )
	util.AddNetworkString( "GetEntityGear_Send" )
	util.AddNetworkString( "GetEntityGear_Receive" )
	util.AddNetworkString( "GetEntityHealth_Send" )
	util.AddNetworkString( "GetEntityHealth_Receive" )
	util.AddNetworkString( "GetEntityName_Send" )
	util.AddNetworkString( "GetEntityName_Receive" )
	util.AddNetworkString( "SendPlayerCooldown" )
	util.AddNetworkString( "SpellData" )
	util.AddNetworkString( "SendVisualTimer" )
	util.AddNetworkString( "SendAllSpells" )
	util.AddNetworkString( "SendPlayerCast" )
	util.AddNetworkString( "SendPlayerSpells" )
	util.AddNetworkString( "SendDamageText" )
	util.AddNetworkString( "SendSelfDamageText" )
	util.AddNetworkString( "SelectedTarget_Send" )
	util.AddNetworkString( "SendSelfItems" )
	util.AddNetworkString( "SetClass" )
	util.AddNetworkString( "CreateNPC" )
	util.AddNetworkString( "GiveAllSpells" )
	util.AddNetworkString( "UpdatePlayerOptions" )
	util.AddNetworkString( "SendPlayerQuest" )
	util.AddNetworkString( "SendPlayerQuestInfo" )
	util.AddNetworkString( "UpdatePlayerQuest" )
	util.AddNetworkString( "RemovePlayerQuest" )
	util.AddNetworkString( "SendPlayerNotification" )
	util.AddNetworkString( "SendPlayerXP" )
	util.AddNetworkString( "ChatMessage" )
	util.AddNetworkString( "SendQuest" )
	util.AddNetworkString( "SimulateClientCast" )
	util.AddNetworkString( "IncurGCD" )
	util.AddNetworkString( "SendPlayerProgress" )
	util.AddNetworkString( "SendClassData" )
	util.AddNetworkString( "SendPlayerClass" )
	util.AddNetworkString( "SendTalentSelection" )
end

local DefaultOwnedSpells = {
	511,
	2142,
	70011,
	20,
	50,
	60
}

local DefaultGear = {
}

local DefaultPresets = {
	{
	"Newbie",
	"Man At Arms",
	{51312, 1100, 60, -10, -10},
	{1,0,50},
	{},
	REGEN_RAGE,
	"class_maa"
	}
}

local DefaultClasses = {
	true,
	true,
	false,
	false,
}

local DefaultCurrency = {
	100,
	1,
}

local DefaultOptions = {}
DefaultOptions.SelectedPreset = 1

local StabSounds = {
	Sound("devin/blackbetty/weapons/hamstring/hamstring1.wav"),
	Sound("devin/blackbetty/weapons/hamstring/hamstring2.wav"),
	Sound("devin/blackbetty/weapons/hamstring/hamstring3.wav")
}

SPELLTYPE_MOBILITY = 1
SPELLTYPE_MELEEDAMAGE = 2
SPELLTYPE_HYBRID = 3
SPELLTYPE_UTILITY = 4
SPELLTYPE_DEFENSIVE = 5
SPELLTYPE_SLOW = 6
SPELLTYPE_SHIELDDAMAGE = 7
SPELLTYPE_SHIELDDEFENSIVE = 8
SPELLTYPE_STEALTH = 99
SPELLTYPE_GROUPUTILITY = 10
SPELLTYPE_RANGEDAMAGE = 11
SPELLTYPE_RANGERUTILITY = 12
SPELLTYPE_MAGICDAMAGE = 13
SPELLTYPE_MAGICSLOW = 14
SPELLTYPE_PASSIVE = 15
SPELLTYPE_SHIELDUTILITY = 16
SPELLTYPE_MAA = 17
SPELLTYPE_RANGER = 18
SPELLTYPE_BRAWLER = 19
SPELLTYPE_BLOODMAGE = 20
SPELLTYPE_SHIELDBEARER = 21
SPELLTYPE_BLADEMASTER = 22
SPELLTYPE_BLADEMASTER2 = 23
REGEN_RAGE = 1
REGEN_ENERGY = 2
REGEN_MANA = 3
REGEN_BLOOD = 4
REGEN_FEROITY = 5
REGEN_AMMO = 6
REGEN_FOCUS = 7
REGEN_HOLYPOWER = 8

RANGE_MELEE = 150
RANGE_BOW = 900
RANGE_CAST = 800


COMBAT_FADETIME = 5

TEAM_GREEN = 1
TEAM_YELLOW = 2
TEAM_WAITING = 3

RESPAWN_TIME = 1
team.SetUp( TEAM_GREEN, "Green", Color( 25, 155, 25, 255 ) )
team.SetUp( TEAM_YELLOW, "Yellow", Color( 255, 255, 25, 255 ) )
team.SetUp( TEAM_WAITING, "Waiting", Color( 155, 155, 155, 255 ) )

ClassData = {}

ClassData.BaseXP = 500;

ClassData.MultXP = 1;

ClassData.DefaultSpells = {
["class_paladin"] = {REGEN_HOLYPOWER, {10912, 19191, 21121, 21120, 48442}},
["class_maa"] = {REGEN_RAGE, {51312, 1100, 60, 81240, 50}},
["class_rogue"] = {REGEN_ENERGY, {51313, 22104, 22105, 41113, 21104}},
["class_ranger"] = {REGEN_FOCUS, {5101, 13403, 11102, 15403, 15405}},
}

ClassData.LevelData = {
	["class_maa"] = {
		[1] = {"AddPassiveBranch", {{10916, 10914, 10918}, 1, 1}},
		[2] = {"AddSpellBranch", {{51314, 51323}, 3, 1}},
		[3] = {"AddSpellBranch", {{20, 4201}, 6, 2}},
		[4] = {"AddSpellBranch", {{6123, 61212}, 8, 3}},
		[5] = {"AddSpellBranch", {{850, 111032}, 10, 4}},
		[6] = {"AddSpellBranch", {{501234, 5032}, 12, 5}},
	},
	["class_ranger"] = {
		[1] = {"AddPassiveBranch", {{10916, 10914, 10918}, 1, 1}},
		[2] = {"AddSpellBranch", {{5016, 5102}, 3, 1}},
		[3] = {"AddSpellBranch", {{13414, 13415}, 6, 2}},
		[4] = {"AddSpellBranch", {{13102, 13152}, 8, 3}},
		[5] = {"AddSpellBranch", {{14405, 14315}, 10, 4}},
		[6] = {"AddSpellBranch", {{11205, 15406}, 12, 5}},
	},
	["class_rogue"] = {
		[1] = {"AddPassiveBranch", {{10916, 10914, 10918}, 1, 1}},
		[2] = {"AddSpellBranch", {{51411, 41316}, 3, 1}},
		[3] = {"AddSpellBranch", {{52104, 20704}, 6, 2}},
		[4] = {"AddSpellBranch", {{25105, 22401}, 8, 3}},
		[5] = {"AddSpellBranch", {{41273, 41276}, 10, 4}},
		[6] = {"AddSpellBranch", {{25414, 25615}, 12, 5}},
	},
	["class_paladin"] = {
		[1] = {"AddPassiveBranch", {{10916, 10914, 10918}, 1, 1}},
		[2] = {"AddSpellBranch", {{51411, 41316}, 3, 1}},
		[3] = {"AddSpellBranch", {{52104, 20704}, 6, 2}},
		[4] = {"AddSpellBranch", {{25105, 22401}, 8, 3}},
		[5] = {"AddSpellBranch", {{41273, 41276}, 10, 4}},
		[6] = {"AddSpellBranch", {{25414, 25615}, 12, 5}},
	},
}




MatchData = {}

MatchData.PlayerProgress = {}
--{[steamid] = {{50, 100, 5}, {1, 2, 0, 0, 0}}}

MatchData.MatchProgress = {}

if(SERVER)then
team.SetSpawnPoint( TEAM_GREEN, {"info_player_terrorist"} )
team.SetSpawnPoint( TEAM_YELLOW, {"info_player_counterterrorist"} )
team.SetSpawnPoint( TEAM_WAITING, {"info_player_start"} )
end


local Players = {}

function GM:PlayerInitialSpawn( ply )
	print("Initial Spawn")
	if(!MatchData.PlayerProgress[ply:SteamID()])then
		MatchData.PlayerProgress[ply:SteamID()] = {{0, ClassData.BaseXP, 1}, {0}}
	end
	
	net.Start("SendPlayerProgress")
	net.WriteTable(MatchData.PlayerProgress[ply:SteamID()][2])
	net.Send(ply)
	
	net.Start("SendClassData")
	net.WriteTable(ClassData)
	net.Send(ply)
	
	ply:SetNoCollideWithTeammates(true)
	ply:SetTeam(3)
	ply:UnSpectate()
end

function GM:PlayerSpawn(ply)
	ply:SetModel("models/devin/rpgdm/testplayer.mdl")
	ply.Recasting = {false, false, false, false, false, false, false}
	ply.InCombat = false
	if(ply.ResourceInfo == nil)then
		SetRegen(ply, REGEN_MANA)
		SetSpells(ply, {-10, -10, -10, -10, -10, -10, -10})
	end
	if(ply.PlayerClass == nil)then
		ply.PlayerClass = "class_default"
	end
	player_manager.SetPlayerClass(ply, ply.PlayerClass)
	player_manager.OnPlayerSpawn(ply)
	player_manager.RunClass(ply, "Spawn")
	
	if(ply.Effects != nil)then
		for q, r in pairs(ply.Effects)do
			r.RemoveMe = true
		end
	end
	
	if(ply.tempSpells)then
		net.Start("SendPlayerSpells")
		net.WriteTable(ply.tempSpells)
		net.Send(ply)
	end
	
	if(!MatchData.PlayerProgress[ply:SteamID()])then
		MatchData.PlayerProgress[ply:SteamID()] = {{0, ClassData.BaseXP, 1}, {0}}
	end
	
	net.Start("SendPlayerClass")
	net.WriteString(ply.PlayerClass)
	net.Send(ply)
	
	ply:SetCollisionGroup(COLLISION_GROUP_DEBRIS_TRIGGER)
end

function HandleCast(pl, target, spellID, simulatepress)
	local r_info = pl.ResourceInfo
	if(pl.NextTimer == nil)then
		pl.NextTimer = 0
	end
	if(CurTime() > pl.NextTimer)then
		for k, v in ipairs (pl.tempSpells)do
			if(spellID == pl.tempSpells[k])then
				for q, r in ipairs (Spells)do
					if(Spells[q].m_iSpellID == pl.tempSpells[k])then
						print("Casting spell #"..pl.tempSpells[k]..".")
						print(Spells[q].m_bRecastWhileCasting)
						if(simulatepress and pl:IsPlayer())then
							net.Start("SimulateClientCast")
							net.WriteFloat(spellID)
							net.Send(pl)
						end
						if(!Spells[q].m_bRecastWhileCasting)then
							if(r_info.Resource >= Spells[q].m_iManaCost)then
								print("Wololo")
								Spells[q]:Cast(pl, target)
								pl:SetNWBool("Casted", true)
								UpdatePlayerResource(pl, -Spells[q].m_iManaCost)
							else
								net.Start( "SendDamageText" )
								net.WriteString("OOM")
								net.WriteVector(Vector(255, 0, 0))
								net.WriteEntity(pl)
								net.Send(pl)
							end
							break
						elseif(Spells[q].m_bRecastWhileCasting and (!pl.Recasting[spellID]))then
							if(r_info.Resource >= Spells[q].m_iManaCost)then
								Spells[q]:Cast(pl, target)
								pl.Recasting[spellID] = true
								pl.CastPosition = pl:GetPos()
								UpdatePlayerResource(pl, -Spells[q].m_iManaCost)
							else
								net.Start( "SendDamageText" )
								net.WriteString("OOM")
								net.WriteVector(Vector(255, 0, 0))
								net.WriteEntity(pl)
								net.Send(pl)
							end
							break
						elseif(Spells[q].m_bRecastWhileCasting and (pl.Recasting[spellID]))then
							Spells[q]:Recast(pl, target)
							pl.Recasting[spellID] = false
							break
						end
					end
				end
			end
		end
	end
	pl.NextTimer = CurTime() + 0.005
end

function SetPlayerPreset(pl, presetIndex)
	local presets = util.JSONToTable(file.Read("rpgdm/playerdata/"..pl:SteamID64().."/presets.txt", "DATA"))
	local class = presets[presetIndex][7]
	local resource = presets[presetIndex][6]
	local spells = presets[presetIndex][3]
	
	pl.PresetName = presets[presetIndex][1]
	SetClass(pl, class)
	SetRegen(pl, resource)
	SetSpells(pl, spells)
	
	MatchData.PlayerProgress[ply:SteamID()] = {{0, ClassData.BaseXP, 1}, {0}}
	AddXP(pl, 0)
end

function GetSpellByID(id)
	if SERVER then
		for q, r in ipairs (Spells)do
			if(Spells[q].m_iSpellID == id)then
				return r
			end
		end
	else
		for q, r in pairs (AllSpells)do
			if(r[6] == id)then
				return r
			end
		end
	end
end

function GetSpellNameByID(id)
	for q, r in ipairs (Spells)do
		if(Spells[q].m_iSpellID == id)then
			return r.m_sName
		end
	end
	return "Invalid Spell"
end

function SetSpells(pl, spells)
	print(pl.builtSpellIcons)
	pl.builtSpellIcons = false
	pl.tempSpells = spells
end

function SetRegen(pl, regen)
	print(regen)
	local r_info = {}
	if(regen == REGEN_RAGE)then
		r_info.Resource = 0
		r_info.ResourceMax = 100
		r_info.ResourceRegen = true
		r_info.RegenOutCombat = true
		r_info.ResourceTimer = 2
		r_info.ResourceRegenAmount = -1
		r_info.ResourceColor = Color(205, 15, 15, 255)
		r_info.ResourceType = REGEN_RAGE
	elseif(regen == REGEN_ENERGY)then
		r_info.Resource = 100
		r_info.ResourceMax = 100
		r_info.ResourceRegen = true
		r_info.ResourceTimer = .1
		r_info.ResourceRegenAmount = 1
		r_info.ResourceColor = Color(185, 185, 0, 255)
		r_info.ResourceType = REGEN_ENERGY
	elseif(regen == REGEN_FEROCITY)then
		r_info.Resource = 0
		r_info.ResourceMax = 3
		r_info.ResourceRegen = false
		r_info.ResourceColor = Color(215, 100, 0, 255)
		r_info.ResourceType = REGEN_FEROCITY
	elseif(regen == REGEN_MANA)then
		r_info.Resource = 150
		r_info.ResourceMax = 150
		r_info.ResourceRegen = true
		r_info.ResourceTimer = .25
		r_info.ResourceRegenAmount = 2
		r_info.ResourceColor = Color(15, 15, 205, 255)
		r_info.ResourceType = REGEN_MANA
	elseif(regen == REGEN_BLOOD)then
		r_info.Resource = 0
		r_info.ResourceMax = 150
		r_info.ResourceRegen = false
		r_info.ResourceColor = Color(145, 15, 15, 255)
		r_info.ResourceType = REGEN_BLOOD
	elseif(regen == REGEN_AMMO)then
		r_info.Resource = 0
		r_info.ResourceMax = 1
		r_info.ResourceRegen = false
		r_info.ResourceColor = Color(145, 15, 15, 255)
		r_info.ResourceType = REGEN_AMMO
	elseif(regen == REGEN_FOCUS)then
		r_info.Resource = 0
		r_info.ResourceMax = 100
		r_info.ResourceTimer = 2
		r_info.ResourceRegenAmount = 5
		r_info.ResourceRegen = true
		r_info.ResourceColor = Color(215, 100, 0, 255)
		r_info.ResourceType = REGEN_FOCUS
	elseif(regen == REGEN_HOLYPOWER)then
		r_info.Resource = 0
		r_info.ResourceMax = 5
		r_info.ResourceRegen = false
		r_info.ResourceColor = Color(185, 185, 0, 255)
	else
		r_info.Resource = 50
		r_info.ResourceMax = 50
		r_info.ResourceRegen = true
		r_info.ResourceTimer = 5
		r_info.ResourceRegenAmount = 25
		r_info.ResourceColor = Color(15, 15, 205, 255)
		r_info.ResourceType = REGEN_MANA
	end
	pl.ResourceInfo = r_info
	net.Start("ReceivePlayerResources")
	net.WriteTable({r_info.Resource, r_info.ResourceMax, r_info.ResourceColor, pl})
	net.Broadcast()
end

function UpdatePlayerResource(ply, amount, filler, regen)
	local newamount = amount
	local r_info = ply.ResourceInfo
	if(filler)then
		if(r_info.ResourceType == REGEN_MANA)then
			return false
		elseif(r_info.ResourceType == REGEN_ENERGY)then
			newamount = amount * 0.75
		elseif(r_info.ResourceType == REGEN_BLOOD)then
			newamount = amount * 1.5
		end
	end
	if(!filler and regen)then
		if(r_info.ResourceType == REGEN_FOCUS and ply:Crouching())then
			newamount = amount * 2
		end
	end
	if(!filler and !regen)then
		if(r_info.ResourceType == REGEN_RAGE and newamount < 0)then
			-- local addhealth = math.Round(((ply:GetMaxHealth()/100)*(newamount*0.15)))
			-- local dmginfo_fbst = DamageInfo()
				-- dmginfo_fbst:SetDamage( addhealth ) 
				-- dmginfo_fbst:SetDamageType( DMG_POISON)
				-- dmginfo_fbst:SetAttacker( ply ) 
			-- ply:TakeDamageInfo( dmginfo_fbst )
		end
	end
	if(r_info.Resource + newamount <= r_info.ResourceMax and r_info.Resource + newamount >= 0)then
		r_info.Resource = r_info.Resource + newamount
		net.Start("ReceivePlayerResources")
		net.WriteTable({r_info.Resource, r_info.ResourceMax, r_info.ResourceColor, ply})
		net.Broadcast()
		return true
	end
	if(r_info.Resource + newamount >= r_info.ResourceMax)then
		r_info.Resource = r_info.ResourceMax
		net.Start("ReceivePlayerResources")
		net.WriteTable({r_info.Resource, r_info.ResourceMax, r_info.ResourceColor, ply})
		net.Broadcast()
		return true
	end
	ply.ResourceInfo = r_info
end

function SendPlayerResources(ply)
	local r_info = ply.ResourceInfo
	if(ply.InCombat and !r_info.RegenOutCombat or !ply.InCombat and (r_info.RegenOutCombat or !r_info.RegenOutCombat))then
		if(r_info.NextResource == nil)then
			r_info.NextResource = CurTime()
		end
		if(r_info.NextResource <= CurTime())then
			UpdatePlayerResource(ply, r_info.ResourceRegenAmount, false, true)
			r_info.NextResource = CurTime() + r_info.ResourceTimer
		end
		ply.ResourceInfo = r_info
	end
end

function GM:Think()
	if(SERVER)then
		Players = player.GetAll()
		for i = 1, table.Count(Players) do
			if( !Players[i].ReceivedAllSpells)then
				AllSpellsTo(Players[i])
				Players[i].ReceivedAllSpells = true
			end
			if((!Players[i].builtSpellIcons or !Players[i].builtSpellIcons and ((!(RPGDM_GameType == "hub") or RPGDM_GameType == nil) or Players[i].TargetDummies == true)) and Players[i].tempSpells)then
				
				local SpellInfo = {
				{{}},
				{{}},
				{{}},
				{{}},
				{{}}
				}
				for s = 1, 5, 1 do
					for k, v in ipairs (Spells)do
						if(Spells[k].m_iSpellID == Players[i].tempSpells[s])then
							if SERVER then
								print("Spell found on spell table at #"..k.." of name: " ..Spells[k].m_sName.."")
								print(Spells[k].m_sName)
								print(s)
								SpellInfo[s][1] = Spells[k].m_sName
								SpellInfo[s][2] = Spells[k].m_sIcon
								SpellInfo[s][3] = Spells[k].m_sToolTip
								SpellInfo[s][4] = Spells[k].m_iRange
								SpellInfo[s][5] = Spells[k].m_iCoolDown
								SpellInfo[s][6] = Spells[k].m_iSpellID
								SpellInfo[s][7] = Spells[k].m_bRequiresTarget
								SpellInfo[s][8] = Spells[k].m_iSpellType
								SpellInfo[s][9] = Spells[k].m_bRecastWhileCasting
								SpellInfo[s][10] = Spells[k].m_sReplaceIcon
								SpellInfo[s][11] = Spells[k].m_iManaCost
							end
						end
					end
				end
				net.Start( "SpellData")
				net.WriteTable(SpellInfo)
				net.Send(Players[i])
				Players[i].builtSpellIcons = true
			end

			if(Players[i].ResourceInfo and Players[i].ResourceInfo.ResourceRegen)then
				SendPlayerResources(Players[i])
			end
			if(Players[i].InCombat and Players[i].LastInCombat and CurTime() >= Players[i].LastInCombat + COMBAT_FADETIME)then
				Players[i].InCombat = false
			end
		end
	end
	AutoAttacks()
end	

function AutoAttacks()
	for i = 1, table.Count(Players) do
		if(Players[i].Contestant)then
			local target = Players[i]:GetNetworkedEntity("Target")
			local weapon = Players[i]:GetActiveWeapon()
			
			if(!weapon.AutoAttacking and !Players[i].DoingCast)then
				weapon.AutoAttacking = true
				Players[i].InCombat = true
			end
			if(weapon.AutoAttacking and target:IsValid() and target:Health() > 0 )then
				if(weapon.NextSwing<=CurTime())then
					weapon.NextSwing = CurTime() + weapon.AttackSpeed
					local LOS = ents.FindInCone( Players[i]:GetPos() - (Players[i]:GetAngles():Forward()*weapon.WeaponReach), Players[i]:GetAimVector(), weapon.WeaponReach*4, 140 )
					local TargetInLOS = false
					
					for k, v in pairs(LOS) do
						if(v:EntIndex() == target:EntIndex())then
							TargetInLOS = true
							break
						end
					end
					
					if(!TargetInLOS)then
						print("LOS")
						return true
					end
				end
			end
		end
	end
end

function PerformMeleeAutoAttack(pl)
	local HitSounds = SliceSounds
	local weapon = pl:GetWeapon("weapon_all")
	local target = pl:GetNetworkedEntity("Target")
	local hitdelay = 0
	local r = 0
	
	if(target == pl)then
		return true
	end

	if(pl:GetNWBool("Casting"))then
		return true
	end
	
	if(target and target:IsValid() and (target:GetPos() - pl:GetPos()):Length() > weapon.WeaponReach)then
	elseif(target and target:IsValid() and (target:GetPos() - pl:GetPos()):Length() < weapon.WeaponReach)then
		if(!pl.InSpellAnimation)then
			if(weapon.WeaponStance == "dagger")then
				pl:DoAnimationEvent(ACT_HL2MP_GESTURE_RANGE_ATTACK_KNIFE)
				hitdelay = 0.15
				HitSounds = StabSounds
			elseif(weapon.WeaponStance == "twohanded")then
				pl:DoAnimationEvent(ACT_HL2MP_GESTURE_RANGE_ATTACK_MELEE2)
				hitdelay = 0.3
			elseif(weapon.WeaponStance == "onehanded")then
					pl:DoAnimationEvent(ACT_HL2MP_GESTURE_RANGE_ATTACK_MELEE)
					hitdelay = 0.15
			elseif(weapon.WeaponStance == "shield")then
				r = 2
				if( r == 1 ) then
					pl:DoAnimationEvent(ACT_HL2MP_GESTURE_RANGE_ATTACK_FIST)
					hitdelay = 0.1
				else
					pl:DoAnimationEvent(ACT_HL2MP_GESTURE_RANGE_ATTACK_KNIFE)
					hitdelay = 0.15
				end
			elseif(weapon.WeaponStance == "fist")then
				pl:DoAnimationEvent(ACT_HL2MP_GESTURE_RANGE_ATTACK_FIST)
				hitdelay = 0.15
			end
		end
		pl:EmitSound("devin/blackbetty/weapons/swing/2h_"..math.random(1,3)..".wav", 100, 100+math.random(-10,10))
		timer.Simple(hitdelay, 
		function()
			if(target and target:IsValid() and weapon and weapon:IsValid())then
				pl:EmitSound("devin/blackbetty/weapons/slam/hit_1.wav", 40, 100+math.random(-20,10))
				if weapon.WeaponStance == "twohanded" then
					player_manager.RunClass( pl, "OnHit", target )
					ParticleEffect( "player_blood", target:GetPos() + Vector(0, 0, 46) + (target:GetAngles():Forward()*6), Angle(0,0,0), pl )
				elseif weapon.WeaponStance == "shield" then
					player_manager.RunClass( pl, "OnHit", r )
				elseif weapon.WeaponStance == "fist" then
					player_manager.RunClass( pl, "OnHit")
				end
				local dmginfo = DamageInfo()
				dmginfo:SetDamage( math.random(weapon.MinWeaponDamage, weapon.MaxWeaponDamage) ) 
				dmginfo:SetDamageType( DMG_GENERIC ) 
				dmginfo:SetAttacker( pl )
				target:TakeDamageInfo( dmginfo )
			end
		end)
	end
	
end

function PerformRangedAutoAttack(pl)
	local hitdelay = 0.1
	local weapon = pl:GetWeapon("weapon_all")
	local target = pl:GetNetworkedEntity("Target")
	
	if(target == pl)then
		return true
	end

	if(pl:GetNWBool("Casting"))then
		return true
	end
	timer.Simple(hitdelay, 
	function()
		if(target and target:IsValid() and (target:GetPos() - pl:GetPos()):Length() > weapon.WeaponReach)then
		elseif(target and target:IsValid() and (target:GetPos() - pl:GetPos()):Length() < weapon.WeaponReach)then
			if(!pl.InSpellAnimation)then
				if(weapon.WeaponStance == "shotgun")then
					pl:EmitSound("weapons/mortar/mortar_fire1.wav", 60, 100+math.random(-10,10))
					timer.Simple(0.3, function()
						pl:EmitSound("weapons/shotgun/shotgun_cock.wav", 25, 100+math.random(-10,10))
					end)
					pl:DoAnimationEvent(ACT_HL2MP_GESTURE_RANGE_ATTACK_SHOTGUN)
					hitdelay = 0.15
					ParticleEffectAttach( "impact_firesmall", PATTACH_POINT_FOLLOW, pl, pl:LookupAttachment("anim_attachment_RH"))
					pl:EmitSound("devin/blackbetty/weapons/castsounds/FireCast.wav", 100, 100+math.random(-10,10))
					ParticleEffectAttach( "impact_firesmall", PATTACH_POINT_FOLLOW, pl, pl:LookupAttachment("anim_attachment_RH"))
					pl:EmitSound("devin/blackbetty/weapons/hit/Fire1.wav", 35, 100+math.random(-10,10))
					target:EmitSound("devin/blackbetty/weapons/hit/Fire1.wav", 35, 100+math.random(-10,10))
					timer.Simple(0.1, function()
						local dmginfo = DamageInfo()
							dmginfo:SetDamage( math.random(weapon.MinWeaponDamage, weapon.MaxWeaponDamage) ) 
							dmginfo:SetDamageType( DMG_GENERIC ) 
							dmginfo:SetAttacker( pl )
						target:TakeDamageInfo( dmginfo )
						ParticleEffect( "impact_firesmall", target:GetPos() + Vector(0, 0, 32), Angle(0,0,0), target )
						player_manager.RunClass( pl, "OnHit", target )
					end)
				end
				if(weapon.WeaponStance == "dual")then
					pl:EmitSound("weapons/mortar/mortar_fire1.wav", 70, 100+math.random(-10,10))
					pl:DoAnimationEvent(ACT_HL2MP_GESTURE_RANGE_ATTACK_DUEL)
					hitdelay = 0.05
					local r = math.random(1,2)
					local l = ""
					if(r == 1)then
						l = "L"
					else
						l = "R"
					end
					ParticleEffectAttach( "impact_firesmall", PATTACH_POINT_FOLLOW, pl, pl:LookupAttachment("anim_attachment_"..l.."H"))
				end
				if(weapon.WeaponStance == "crossbow")then
					pl:EmitSound("devin/blackbetty/weapons/bow/BowRelease01.wav", 80, 100+math.random(-10,10))
					pl:DoAnimationEvent(ACT_HL2MP_GESTURE_RANGE_ATTACK_CROSSBOW)
					-- timer.Simple(0.1, function()
						-- pl:DoAnimationEvent(ACT_HL2MP_GESTURE_RELOAD_AR2)
					-- end)
					timer.Simple(0.8, function()
						pl:EmitSound("devin/blackbetty/weapons/bow/BowPullback0"..math.random(1,3)..".wav", 70, 100+math.random(-10,10))
					end)
					hitdelay = ((pl:GetPos() - target:GetPos()):Length()/1800)
					ParticleEffect( "pummel_hit", pl:GetPos() + (pl:GetAngles():Forward()*48) + Vector(0, 0, 45) + (pl:GetAngles():Right()*16), Angle(0,0,0), pl )
					LaunchProjectile(pl, target, 0, "pummel_hit", "", "autoshot", "devin/blackbetty/weapons/bow/BowArrowInFlightLoop.wav", hitdelay, 1800, "models/crossbow_bolt.mdl")
					timer.Simple(hitdelay, function()
						local dmginfo = DamageInfo()
							dmginfo:SetDamage( math.random(weapon.MinWeaponDamage, weapon.MaxWeaponDamage) ) 
							dmginfo:SetDamageType( DMG_GENERIC ) 
							dmginfo:SetAttacker( pl )
						target:TakeDamageInfo( dmginfo )
						target:EmitSound("devin/blackbetty/weapons/bow/ArrowHit0"..math.random(1,3)..".wav", 100, 100+math.random(-10,10))
						ParticleEffect( "pummel_hit", target:GetPos() + Vector(0, 0, 45), Angle(0,0,0), target )
						player_manager.RunClass( pl, "OnHit", target )
					end)
				end
				if(weapon.WeaponStance == "mage")then
					pl:EmitSound("devin/blackbetty/weapons/castsounds/ShadowCast.wav", 80, 100+math.random(-10,10))
					pl:DoAnimationEvent(ACT_HL2MP_GESTURE_RANGE_ATTACK_SLAM)
					-- timer.Simple(0.1, function()
						-- pl:DoAnimationEvent(ACT_HL2MP_GESTURE_RELOAD_AR2)
					-- end)
					local myhitdelay = ((pl:GetPos() - target:GetPos()):Length()/1800)
					ParticleEffect( "pummel_hit", pl:GetPos() + (pl:GetAngles():Forward()*48) + Vector(0, 0, 45) + (pl:GetAngles():Right()*16), Angle(0,0,0), pl )
					LaunchProjectile(pl, target, 0, "pummel_hit", "", "blood_hands", "ambient/atmosphere/city_tone.wav", myhitdelay, 1600, "models/crossbow_bolt.mdl")
					timer.Simple(hitdelay, function()
						local dmginfo = DamageInfo()
							dmginfo:SetDamage( math.random(weapon.MinWeaponDamage, weapon.MaxWeaponDamage) ) 
							dmginfo:SetDamageType( DMG_GENERIC ) 
							dmginfo:SetAttacker( pl )
						target:TakeDamageInfo( dmginfo )
						target:EmitSound("devin/blackbetty/weapons/bow/ArrowHit0"..math.random(1,3)..".wav", 100, 100+math.random(-10,10))
						ParticleEffect( "pummel_hit", target:GetPos() + Vector(0, 0, 45), Angle(0,0,0), target )
						player_manager.RunClass( pl, "OnHit", target )
					end)
				end
			end
		end
	end)
end


function AllSpellsTo(ply)
	transcribe = {}
	
	for i = 1, table.getn(Spells) do
		transcribe[i] = {}
		for j = 1, 7 do
			transcribe[i][j] = nil
		end
	end
	
	for k, v in ipairs (Spells)do
		transcribe[k][1] = Spells[k].m_sName
		transcribe[k][2] = Spells[k].m_sIcon
		transcribe[k][3] = Spells[k].m_sToolTip
		transcribe[k][4] = Spells[k].m_iRange
		transcribe[k][5] = Spells[k].m_iCoolDown
		transcribe[k][6] = Spells[k].m_iSpellID
		transcribe[k][7] = Spells[k].m_bRequiresTarget
		transcribe[k][8] = Spells[k].m_iSpellType
		transcribe[k][9] = Spells[k].m_bRecastWhileCasting
		transcribe[k][10] = Spells[k].m_sReplaceIcon
		transcribe[k][11] = Spells[k].m_iManaCost
	end
	
	net.Start( "SendAllSpells")
	net.WriteTable(transcribe)
	net.Send(ply)
end

function SendDamageText( ent, dmginfo )
	ColorToSend = nil
	local atk = dmginfo:GetAttacker()
	if(atk:IsPlayer())then
		if(atk.ResourceInfo.ResourceType == REGEN_BLOOD and dmginfo:GetDamage() > 0)then
			vamp_amount = math.Round((dmginfo:GetDamage()*0.1))
			UpdatePlayerResource(atk, vamp_amount, false, true)
		end
	end
	if(ent:IsPlayer() and ent.ResourceInfo.ResourceType == REGEN_RAGE and dmginfo:GetDamage() > 0)then
		local rage_amount = math.Round((dmginfo:GetDamage()/ent:GetMaxHealth())*100)
		UpdatePlayerResource(ent, rage_amount, false, true)
	end
	-- if(ent:IsPlayer() and ent.ResourceInfo.ResourceType == REGEN_FOCUS and dmginfo:GetDamage() > 0)then
		-- local rage_amount = (math.Round((dmginfo:GetDamage()/ent:GetMaxHealth())*100))*-1
		-- UpdatePlayerResource(ent, rage_amount, false, true)
	-- end
	if(dmginfo:GetAttacker():IsPlayer() and dmginfo:GetAttacker().ResourceInfo.ResourceType == REGEN_FOCUS and dmginfo:GetAttacker().ResourceInfo.Resource == dmginfo:GetAttacker().ResourceInfo.ResourceMax)then
		dmginfo:SetDamage(dmginfo:GetDamage()*2)
		UpdatePlayerResource(dmginfo:GetAttacker(), dmginfo:GetAttacker().ResourceInfo.ResourceMax*-1, false, false)
	end
	local avoided = tostring(DamageAvoided(ent, dmginfo))
		if(a == a)then
			if(ent.ArmorStat and ent.ArmorStat > 0 and dmginfo:GetAttacker() != ent and !(dmginfo:GetDamageType() == DMG_SLASH or dmginfo:GetDamageType() == DMG_ENERGYBEAM) )then
				if(dmginfo:GetDamage()-ent.ArmorStat > 0)then
					dmginfo:SetDamage(dmginfo:GetDamage()-ent.ArmorStat)
					PlayerInjured(ent, dmginfo)
				else
					ent:StopParticles()
					ent:EmitSound("devin/blackbetty/weapons/2hMaceHitMetalShield1a.wav", 150, 100)
					dmginfo:ScaleDamage(0)
					if(dmginfo:GetAttacker():IsPlayer())then
						if(ent:IsPlayer())then
							net.Start( "SendDamageText" )
							net.WriteString("aaDeflected")
							net.WriteVector(Vector(30, 30, 155))
							net.WriteEntity(ent)
							net.Send(ent)
						end
						net.Start( "SendDamageText" )
						net.WriteString("Deflected")
						net.WriteVector(Vector(30, 30, 155))
						net.WriteEntity(ent)
						net.Send(dmginfo:GetAttacker())
					end
					return dmginfo
				end
			end
			if(avoided != "false" and !(dmginfo:GetDamageType() == DMG_SLASH or dmginfo:GetDamageType() == DMG_ENERGYBEAM or dmginfo:GetDamageType() == DMG_CRUSH))then
				if(avoided == "Parry")then
					local pos = ent:GetAngles() - atk:GetAngles()
					if(pos.y >= 90 and pos.y <= 270)then 
						ent:StopParticles()
						ent:EmitSound("devin/blackbetty/weapons/parry.wav", 140, 100+math.random(-40,40))
						dmginfo:ScaleDamage(0)
						net.Start( "SendDamageText" )
						net.WriteString("aa"..avoided.."")
						net.WriteVector(Vector(30, 30, 155))
						net.WriteEntity(ent)
						net.Send(dmginfo:GetAttacker())
						return dmginfo
					else
						dmginfo:ScaleDamage(1)
						PlayerInjured(ent, dmginfo)
					end
				elseif(avoided == "Dodge")then
					local pos = ent:GetAngles() - atk:GetAngles()
					if(pos.y >= 90 and pos.y <= 270)then 
						ent:StopParticles()
						ent:EmitSound("devin/blackbetty/weapons/dodge.wav", 140, 100+math.random(20,40))
						dmginfo:ScaleDamage(0)
						net.Start( "SendDamageText" )
						net.WriteString("aa"..avoided.."")
						net.WriteVector(Vector(30, 30, 155))
						net.WriteEntity(ent)
						net.Send(dmginfo:GetAttacker())
						return dmginfo
					else
						dmginfo:ScaleDamage(1)
						PlayerInjured(ent, dmginfo)
					end
				elseif(avoided == "Block")then
					local pos = ent:GetAngles() - atk:GetAngles()
					if(pos.y >= 90 and pos.y <= 270)then
						print(avoided)
						ent:EmitSound("devin/blackbetty/weapons/2hMaceHitPlateCrit.wav", 140, 100+math.random(-40,40))
						dmginfo:ScaleDamage(0.5)
						net.Start( "SendDamageText" )
						net.WriteString("aaaa"..dmginfo:GetDamage().."("..dmginfo:GetDamage().." blocked)")
						net.WriteVector(Vector(30, 30, 155))
						net.WriteEntity(ent)
						net.Send(dmginfo:GetAttacker())
						return dmginfo
					else
						dmginfo:ScaleDamage(1)
						PlayerInjured(ent, dmginfo)
					end
					
				end
			else
				PlayerInjured(ent, dmginfo)
			end
		end
	if( ent:IsPlayer())then
		net.Start( "SendSelfDamageText" )
		
		if(dmginfo:GetDamage() < 0)then
			net.WriteString("+"..math.abs(dmginfo:GetDamage()).."")
			ColorToSend = Vector(50, 255, 50)
		else
			ent.InCombat = true
			ent.LastInCombat = CurTime()
			net.WriteString(dmginfo:GetDamage())
			if(dmginfo:GetDamageType() == DMG_SLASH)then
				ColorToSend = Vector(200, 0, 0)
				elseif( dmginfo:GetDamageType() == DMG_BURN )then
					ColorToSend = Vector(255, 165, 0)
				elseif( dmginfo:GetDamageType() == DMG_CRUSH )then
					ColorToSend = Vector(139, 69, 19)
				elseif( dmginfo:GetDamageType() == DMG_DROWN )then
					ColorToSend = Vector(0, 0, 255)
				elseif( dmginfo:GetDamageType() == DMG_POISON )then
					ColorToSend = Vector(0, 255, 0)
				elseif( dmginfo:GetDamageType() == DMG_GENERIC )then
					ColorToSend = Vector(0, 225, 225)
				elseif( dmginfo:GetDamageType() == DMG_ENERGYBEAM )then
					ColorToSend = Vector(45, 45, 235)
				else
					ColorToSend = Vector(255, 255, 255)
			end	
		end
		net.WriteVector(ColorToSend)
		net.Send(ent)
	end
	
	if (dmginfo:GetAttacker():GetClass() == "npc_rpgdm" and dmginfo:GetAttacker().IsPet) then
		net.Start( "SendDamageText" )
		net.WriteEntity(ent)
		if(dmginfo:GetDamage() < 0)then
			net.WriteString("+"..math.abs(dmginfo:GetDamage()).."")
			ColorToSend = Vector(50, 255, 50)
		else
			net.WriteString(dmginfo:GetDamage())
			ColorToSend = Vector(205, 155, 0)
		end
		
		net.WriteVector(ColorToSend)
		net.Send(dmginfo:GetAttacker().Owner)
	end
	
	if (dmginfo:GetAttacker():IsPlayer()) then
		net.Start( "SendDamageText" )
		net.WriteEntity(ent)
		if(dmginfo:GetDamage() < 0)then
			net.WriteString("+"..math.abs(dmginfo:GetDamage()).."")
			ColorToSend = Vector(50, 255, 50)
		else
			net.WriteString(dmginfo:GetDamage())
			if(dmginfo:GetDamageType() == DMG_SLASH)then
				ColorToSend = Vector(200, 0, 0)
				elseif( dmginfo:GetDamageType() == DMG_BURN )then
					ColorToSend = Vector(255, 165, 0)
				elseif( dmginfo:GetDamageType() == DMG_CRUSH )then
					ColorToSend = Vector(139, 69, 19)
				elseif( dmginfo:GetDamageType() == DMG_DROWN )then
					ColorToSend = Vector(0, 0, 255)
				elseif( dmginfo:GetDamageType() == DMG_POISON )then
					ColorToSend = Vector(0, 255, 0)
				elseif( dmginfo:GetDamageType() == DMG_GENERIC )then
					ColorToSend = Vector(225, 225, 0)
				elseif( dmginfo:GetDamageType() == DMG_ENERGYBEAM )then
					ColorToSend = Vector(45, 45, 235)
				else
					ColorToSend = Vector(255, 255, 255)
			end	
		end
		
		net.WriteVector(ColorToSend)
		net.Send(dmginfo:GetAttacker())
	end
	
	if(dmginfo:GetDamage() < 0)then
		DoHealing(ent, math.abs(dmginfo:GetDamage()))
	end
end
hook.Add( "EntityTakeDamage", "SendDamageText", SendDamageText )

function DoHealing(ent, amt)

	local maxhp = ent:GetMaxHealth()
	local curhp = ent:Health()
	
	if((maxhp - curhp)<amt)then
		ent:SetHealth(curhp+(maxhp-curhp))
	else
		ent:SetHealth(curhp+amt)
	end
end

function PlayerSpawn_GearReset(ply)
	ply:UnSpectate()
	if(ply and ply:IsValid())then
		if(ply:GetNWEntity("MainWep") and ply:GetNWEntity("MainWep"):IsValid())then
				ply:GetNWEntity("MainWep"):Remove()
				ply:SetNWEntity("MainWep", nil)
			end
			if(ply:GetNWEntity("OffWep") and ply:GetNWEntity("OffWep"):IsValid())then
				ply:GetNWEntity("OffWep"):Remove()
				ply:SetNWEntity("OffWep", nil)
		end
		if(ply.Corpse != nil)then
			if(ply.VisibleItems != nil and table.Count(ply.VisibleItems) > 0)then
				for k, v in pairs(ply.VisibleItems)do
					if v:IsPlayer() then return false end
					v:SetParent(ply)
				end
				ply.Corpse:Remove()
				ply.Corpse = nil
			end
		end
	end
end
hook.Add( "PlayerSpawn", "RPGDM_PlayerSpawn_GearReset", PlayerSpawn_GearReset );

function SendPlayerInventory(ply)
	local gear = nil
	local spells = nil
	local classes = nil
	local currency = nil
	local presets = nil
	if(!file.Exists("rpgdm/playerdata/"..ply:SteamID64().."/currency.txt", "DATA"))then
		print("DATA FILES FOR: ("..ply:GetName().."; "..ply:SteamID64()..") NOT FOUND")
		file.CreateDir( "rpgdm/playerdata/"..ply:SteamID64().."" )
		file.Write("rpgdm/playerdata/"..ply:SteamID64().."/spells.txt", util.TableToJSON(DefaultOwnedSpells))
		file.Write("rpgdm/playerdata/"..ply:SteamID64().."/gear.txt", util.TableToJSON(DefaultGear))
		file.Write("rpgdm/playerdata/"..ply:SteamID64().."/classes.txt", util.TableToJSON(DefaultClasses))
		file.Write("rpgdm/playerdata/"..ply:SteamID64().."/currency.txt", util.TableToJSON(DefaultCurrency))
		file.Write("rpgdm/playerdata/"..ply:SteamID64().."/presets.txt", util.TableToJSON(DefaultPresets))
		file.Write("rpgdm/playerdata/"..ply:SteamID64().."/options.txt", util.TableToJSON(DefaultOptions))
	end
	gear = file.Read("rpgdm/playerdata/"..ply:SteamID64().."/gear.txt", "DATA")
	spells = file.Read("rpgdm/playerdata/"..ply:SteamID64().."/spells.txt", "DATA")
	classes = file.Read("rpgdm/playerdata/"..ply:SteamID64().."/classes.txt", "DATA")
	currency = file.Read("rpgdm/playerdata/"..ply:SteamID64().."/currency.txt", "DATA")
	presets = file.Read("rpgdm/playerdata/"..ply:SteamID64().."/presets.txt", "DATA")
	options = file.Read("rpgdm/playerdata/"..ply:SteamID64().."/options.txt", "DATA")
	
	timer.Simple(0.25, function()
		local AllPlayerData = {gear, spells, classes, currency, presets, options}
		net.Start("SendPlayerInventory")
		net.WriteTable(AllPlayerData)
		net.Send(ply)
	end)
end

function SetFaction(ply, command, args)
	print(args[1])
	local faction = tonumber(args[1])
	if(faction >= 0 and faction < 64)then
		ply.Faction = faction
		print(ply:GetName().."'s faction set to Faction ID #"..faction..".")
	else
		print("Faction not within acceptable range.")
		return true
	end
end

function SetTargetFaction(ply, command, args)
	print(args[1])
	local target = ply:GetNWEntity("Target")
	local faction = tonumber(args[1])
	if(target and faction >= 0 and faction < 64)then
		target.Faction = faction
		print(target:GetName().."'s faction set to Faction ID #"..faction..".")
	elseif(faction < 0 or faction >64)then
		print("Faction not within acceptable range. (0-64)")
		return true
	elseif(target == nil)then
		print("Target does not exist.")
		return true
	end
end

function GivePlayerSelectedPreset(pl)
	if(!file.Exists("rpgdm/playerdata/"..pl:SteamID64().."/currency.txt", "DATA"))then
		print("DATA FILES FOR: ("..pl:GetName().."; "..pl:SteamID64()..") NOT FOUND")
		file.CreateDir( "rpgdm/playerdata/"..pl:SteamID64().."" )
		file.Write("rpgdm/playerdata/"..pl:SteamID64().."/spells.txt", util.TableToJSON(DefaultOwnedSpells))
		file.Write("rpgdm/playerdata/"..pl:SteamID64().."/gear.txt", util.TableToJSON(DefaultGear))
		file.Write("rpgdm/playerdata/"..pl:SteamID64().."/classes.txt", util.TableToJSON(DefaultClasses))
		file.Write("rpgdm/playerdata/"..pl:SteamID64().."/currency.txt", util.TableToJSON(DefaultCurrency))
		file.Write("rpgdm/playerdata/"..pl:SteamID64().."/presets.txt", util.TableToJSON(DefaultPresets))
		file.Write("rpgdm/playerdata/"..pl:SteamID64().."/options.txt", util.TableToJSON(DefaultOptions))
		file.Write("rpgdm/playerdata/"..pl:SteamID64().."/activequests.txt", util.TableToJSON({}))
		file.Write("rpgdm/playerdata/"..pl:SteamID64().."/completedquests.txt", util.TableToJSON({}))
	end
	local presets = util.JSONToTable(file.Read("rpgdm/playerdata/"..pl:SteamID64().."/presets.txt", "DATA"))
	local options = util.JSONToTable(file.Read("rpgdm/playerdata/"..pl:SteamID64().."/options.txt", "DATA"))
	local presetIndex = options.SelectedPreset
	
	local class = presets[presetIndex][7] or "class_maa"
	local resource = presets[presetIndex][6] or REGEN_RAGE
	local spells = presets[presetIndex][3] or {51312, 1100, 60, 81240, 50}
	pl.PresetName = presets[presetIndex][1] or "Newbie"
	SetClass(pl, nil, {pl:GetName(), class})
	SetRegen(pl, resource)
	SetSpells(pl, spells)
	ApplyTalents(pl)
	AddXP(pl, 0)
	
end

function StripPlayer(ply)
	local classinfo = {ply:GetName(), "class_default"}
	SetClass(ply, nil, classinfo)
	SetSpells(ply, {-10, -10, -10, -10, -10, -10, -10})
	SetRegen(ply, REGEN_MANA)
	player_manager.SetPlayerClass(ply, ply.PlayerClass)
	player_manager.OnPlayerSpawn( ply )
	player_manager.RunClass( ply, "Spawn" )
	if(ply.tempSpells)then
		net.Start("SendPlayerSpells")
		net.WriteTable(ply.tempSpells)
		net.Send(ply)
	end
end

function GetDistanceToTarget(ply, command, args)
	local target = ply:GetNWEntity("Target")
	print((target:GetPos() - ply:GetPos()):Length())
end

function SetTargetMe(ply, command, args)
	local target = ply:GetNWEntity("Target")
	target:SetNWEntity("Target", ply)
end

function SetClass(ply, command, args)
	if(SERVER)then
		for k, v in pairs(player.GetHumans())do
			if(v:GetName() == args[1] and args[2] != nil)then
				v.PlayerClass = args[2]
			end
		end
	end
	if(CLIENT)then
		net.Start("SetClass")
		net.WriteString(args[1])
		net.SendToServer()
	end
end

net.Receive( "SpawnWithPreset", function(len, ply)
	local info = net.ReadTable()
	local classname = info[3]
	info[3] = {}
	table.insert(info[3], ply:GetName())
	table.insert(info[3], classname)
	ply:Kill()
	ply.PresetName = info[4]
	SetClass( ply, nil, info[3])
	SetSpells(ply, info[1])
	SetRegen(ply, info[2])
	ApplyTalents(ply)
	AddXP(ply, 0)
end)

net.Receive( "SetClass", function(len, ply)
	local class = net.ReadString()
	v.PlayerClass = class
end)

 net.Receive( "SpellCast", function()

     
    local spell_info = net.ReadTable()
	local pl = spell_info[1]
	local target = spell_info[2]
	local spellID = spell_info[3]
	
	HandleCast(pl, target, spellID)
	
end)

net.Receive( "CreateNPC", function(len, ply)
	local MobID = net.ReadFloat()
	local hitpos = net.ReadVector()
  
	CreateNPC(MobID, hitpos)
end)

net.Receive( "GetEntityHealth_Send", function(len, ply)
	
	local ent = net.ReadEntity()
	if(ent and ent:IsValid())then
		net.Start( "GetEntityHealth_Receive" )
		net.WriteEntity(ent)
		if(ent:IsNPC())then
			net.WriteFloat(ent:GetMaxHealth())
		end
		net.WriteFloat(ent:GetMaxHealth())
		net.Send(ply)
	end
end)

net.Receive( "GetEntityGear_Send", function(len, ply)
	local ent = net.ReadEntity()
	if(!ent.tempEquippedItems)then
		return true
	end
	if(ent and ent:IsValid())then
		net.Start( "GetEntityGear_Receive" )
		net.WriteTable(ent.tempEquippedItems)
		net.Send(ply)
	end
end)

net.Receive( "SelectedTarget_Send", function(len, ply)
		local target = net.ReadEntity()
		ply:SetNWEntity("Target", target)
end)

net.Receive( "ReceiveGameType", function(len, ply)
		local gtype = RPGDM_GameType
		net.Start( "SendGameType" )
		net.WriteString(gtype)
		net.Send(ply)
end)

net.Receive( "GetEntityName_Send", function(len, ply)
	local ent = net.ReadEntity()
	
	if(ent and ent:IsValid())then
		local str = ent:GetName()
		local mytable = {
		ent,
		str
		}
		net.Start( "GetEntityName_Receive" )
		net.WriteTable(mytable)
		net.Send(ply)
	end
end)

net.Receive( "GiveAllSpells", function(len, ply)
	AllSpellsTo(ply)
end)

net.Receive( "ChangePlayerSpells", function(len, ply)
	local NewSpells = net.ReadTable()
	ply.tempSpells = NewSpells
	PrintTable(ply.tempSpells)
end)

net.Receive( "UpdatePlayerPresets", function(len, ply)
	local presets = net.ReadString()
	file.Write("rpgdm/playerdata/"..ply:SteamID64().."/presets.txt", presets)
end)

net.Receive( "UpdatePlayerOptions", function(len, ply)
	local options = net.ReadString()
	file.Write("rpgdm/playerdata/"..ply:SteamID64().."/options.txt", options)
end)

net.Receive( "SendTalentSelection", function(len, ply) 
	local tbl = net.ReadTable()
	if(#MatchData.PlayerProgress[ply:SteamID()][2] < #tbl)then
		DataMismatch(ply)
		return
	end
	
	for k, v in pairs(MatchData.PlayerProgress[ply:SteamID()][2]) do
		if(v != tbl[k])then
			if(v!=0 and tbl[k] != v)then
				DataMismatch(ply)
				return
			end
		end
	end
	
	MatchData.PlayerProgress[ply:SteamID()][2] = tbl
	ApplyTalents(ply)
	
	net.Start("SendPlayerProgress")
	net.WriteTable(MatchData.PlayerProgress[ply:SteamID()][2])
	net.Send(ply)
end)

function ApplyTalents(ply)
	local talents = MatchData.PlayerProgress[ply:SteamID()][2]
	local class = player_manager.GetPlayerClass(ply)
	local leveldata = ClassData.LevelData[class]
	
	if(leveldata and talents)then
		for k, v in pairs(talents)do
			if(v != 0)then
			local upgrade_type = leveldata[k][1]
				if(upgrade_type == "AddSpellBranch")then
					local spell_id = leveldata[k][2][1][v]
					local spell_slot = leveldata[k][2][3]
					local spells = ply.tempSpells
					spells[spell_slot] = spell_id
					SetSpells(ply, spells)
				end
				if(upgrade_type == "AddPassiveBranch")then
					local spell_id = leveldata[k][2][1][v]
					local spell = GetSpellByID(spell_id)
					spell:Effect(ply)
				end
			end
		end
	end
end

function RemoveTalents(ply)
	local talents = MatchData.PlayerProgress[ply:SteamID()][2]
	local class = player_manager.GetPlayerClass(ply)
	local leveldata = ClassData.LevelData[class]
	
	if(leveldata and talents)then
		for k, v in pairs(talents)do
			if(v != 0)then
				local upgrade_type = leveldata[k][1]
				if(upgrade_type == "AddPassiveBranch")then
					local spell_id = leveldata[k][2][1][v]
					local spell = GetSpellByID(spell_id)
					spell:RemoveEffect(ply)
				end
			end
		end
	end
end

function DataMismatch(ply)
	
end

function UpdatePlayerOptions(ply, options)
	file.Write("rpgdm/playerdata/"..ply:SteamID64().."/options.txt", options)
end

function SendPlayerNotification(pl, text, col, font)
	local tbl = {text, col, font}
	net.Start("SendPlayerNotification")
	net.WriteTable(tbl)
	net.Send(pl)
end

function CompletePlayerQuest(pl, qID)
	local CompletedQuests = util.JSONToTable(file.Read("rpgdm/playerdata/"..pl:SteamID64().."/completedquests.txt", "DATA"))
	local AllQuests = util.JSONToTable(file.Read("rpgdm/playerdata/"..pl:SteamID64().."/activequests.txt", "DATA"))
	local QCompData = {}
	local QuestIndex = 0
	QCompData[1] = {}
	for k, v in ipairs(Quest)do
		if(v.QuestID == qID)then
			for i, a in pairs(CompletedQuests)do
				if(a[1] == qID)then
					return false
				end				
			end
			for i, a in pairs(AllQuests)do
				if(a[1] == qID)then
					QuestIndex = i
				end				
			end
			if(v.Daily)then
				QCompData[1] = qID
				QCompData[2] = "daily"
				QCompData[3] = {os.date("%d")}
			elseif(v.Weekly)then
				QCompData[1] = qID
				QCompData[2] = "weekly"
				QCompData[3] = {os.date("%W")}
			else
				QCompData[1] = qID
				QCompData[2] = "perma"
			end
			table.insert(CompletedQuests, QCompData)
			table.remove(AllQuests, QuestIndex)
			file.Write("rpgdm/playerdata/"..pl:SteamID64().."/completedquests.txt", util.TableToJSON(CompletedQuests))
			file.Write("rpgdm/playerdata/"..pl:SteamID64().."/activequests.txt", util.TableToJSON(AllQuests))
			net.Start("RemovePlayerQuest")
			net.WriteFloat(qID)
			net.Send(pl)
			return true
		end
	end
end

function SetPlayerOnQuest(pl, qID)
	--PrintTable(Quest)
	local QuestInfo = {}
	if(!file.Exists("rpgdm/playerdata/"..pl:SteamID64().."/activequests.txt", "DATA"))then
		file.Write("rpgdm/playerdata/"..pl:SteamID64().."/activequests.txt", util.TableToJSON({}))
	end
	local AllQuests = util.JSONToTable(file.Read("rpgdm/playerdata/"..pl:SteamID64().."/activequests.txt", "DATA"))
	if(#AllQuests == 5)then
		print(""..pl:GetName().." has too many quests to continue.")
		return false
	end
	for k, v in ipairs(Quest)do
		print(v.QuestID)
		if(v.QuestID == tonumber(qID))then
			local qtable = {}
			qtable[1] = tonumber(qID)
			qtable[2] = {}
			qtable[3] = v.Objectives
			qtable[4] = false
			qtable[5] = v.Name
			print(""..pl:GetName().." has received the quest '"..v.Name.."'")
			for i = 1, #qtable[3], 1 do
				qtable[2][i] = 0
			end
			table.insert(AllQuests, qtable)
			for b, n in pairs(AllQuests)do
				for o, p in pairs(Quest)do
					if(p.QuestID == n[1])then
						PrintTable(p)
						QuestInfo[b] = {}
						QuestInfo[b].QuestID = p.QuestID
						QuestInfo[b].Name = p.Name
						QuestInfo[b].Text = p.Text
						QuestInfo[b].CompleteText = p.CompleteText
						QuestInfo[b].Objectives = p.Objectives
						QuestInfo[b].ObjectiveText = p.ObjectiveText
					end
				end
			end
			net.Start("SendPlayerQuestInfo")
			net.WriteTable(QuestInfo)
			net.Send(pl)
			file.Write("rpgdm/playerdata/"..pl:SteamID64().."/activequests.txt", util.TableToJSON(AllQuests))
			net.Start("SendPlayerQuest")
			net.WriteTable(AllQuests)
			net.WriteBit(1)
			net.Send(pl)
			break
		end
	end
end

function ClearAllQuests(pl)
	file.Write("rpgdm/playerdata/"..pl:SteamID64().."/activequests.txt", util.TableToJSON({}))
end

function RefreshPlayerQuests(pl)
	local QuestInfo = {}
	if(!file.Exists("rpgdm/playerdata/"..pl:SteamID64().."/activequests.txt", "DATA"))then
		file.Write("rpgdm/playerdata/"..pl:SteamID64().."/activequests.txt", util.TableToJSON({}))
	end
	local AllQuests = util.JSONToTable(file.Read("rpgdm/playerdata/"..pl:SteamID64().."/activequests.txt", "DATA"))
	for b, n in pairs(AllQuests)do
		for o, p in pairs(Quest)do
			if(p.QuestID == n[1])then
				PrintTable(p)
				QuestInfo[b] = {}
				QuestInfo[b].QuestID = p.QuestID
				QuestInfo[b].Name = p.Name
				QuestInfo[b].Text = p.Text
				QuestInfo[b].CompleteText = p.CompleteText
				QuestInfo[b].Objectives = p.Objectives
				QuestInfo[b].ObjectiveText = p.ObjectiveText
			end
		end
	end
	net.Start("SendPlayerQuestInfo")
	net.WriteTable(QuestInfo)
	net.Send(pl)
	net.Start("SendPlayerQuest")
	net.WriteTable(AllQuests)
	net.Send(pl)
end

function SendQuestUpdateNotification(pl, qID, EntID, num, maxnum)
	local QuestInfo = {}
	QuestInfo[1] = {}
	local StringToSend = ""
	local ObjText = ""
	local ObjID = 0
	for k, v in ipairs(Quest)do
		if(v.QuestID == qID)then
			for i, b in ipairs(v.Objectives)do
				if(b[2][1] == EntID)then
					ObjID = i
					ObjText = v.ObjectiveText[ObjID]
					break
				end
			end
		end
	end
	StringToSend = ""..ObjText..": "..num.."/"..maxnum..""
	print(StringToSend)
	SendPlayerNotification(pl, StringToSend, Color(255, 255, 0), "HUDText_Quests")
end

function UpdatePlayerQuest(pl, tbl)
	local QuestInfo = {}
	QuestInfo[1] = {}
	local AllQuests = util.JSONToTable(file.Read("rpgdm/playerdata/"..pl:SteamID64().."/activequests.txt", "DATA"))
	local UpdateType = tbl[1]
	local ObjID = tbl[2]
	local ObjAmt = tbl[3]
	local qtable = {}
	for k, v in pairs(AllQuests)do
		if(!v[4])then
			for i, b in pairs(v[3])do
				if(b[2][1] == ObjID)then
					if(AllQuests[k][2][i] == b[2][2])then
						return false
					end
					if(b[1] == OBJECTIVE_KILL and UpdateType == "kill")then
						AllQuests[k][2][i] = math.Clamp(v[2][i] + ObjAmt, 0, b[2][2])
					elseif(b[1] == OBJECTIVE_COLLECT and UpdateType == "collect")then
						AllQuests[k][2][i] = math.Clamp(v[2][i] + ObjAmt, 0, b[2][2])
						print("Collection Objective updated - "..AllQuests[k][2][i].."/"..b[2][2].."")
					elseif(b[1] == OBJECTIVE_INTERACT and UpdateType == "interact")then
						AllQuests[k][2][i] = 1
						print("Interaction Objective completed")
					elseif(b[1] == OBJECTIVE_SPEAK and UpdateType == "speak")then
						AllQuests[k][2][i] = 1
					elseif(b[1] == OBJECTIVE_ESCORTNPC and UpdateType == "escortnpc")then
						AllQuests[k][2][i] = 1
					elseif(b[1] == OBJECTIVE_ESCORTLOCATION and UpdateType == "escortlocation")then
						AllQuests[k][2][i] = 1
					qtable = {AllQuests[k][1], AllQuests[k][2]}
					end
					SendQuestUpdateNotification(pl, AllQuests[k][1], ObjID, AllQuests[k][2][i], b[2][2])
					file.Write("rpgdm/playerdata/"..pl:SteamID64().."/activequests.txt", util.TableToJSON(AllQuests))
					for b, n in pairs(AllQuests)do
						for o, p in pairs(Quest)do
							if(p.QuestID == n[1])then
								PrintTable(p)
								QuestInfo[b] = {}
								QuestInfo[b].QuestID = p.QuestID
								QuestInfo[b].Name = p.Name
								QuestInfo[b].Text = p.Text
								QuestInfo[b].CompleteText = p.CompleteText
								QuestInfo[b].Objectives = p.Objectives
								QuestInfo[b].ObjectiveText = p.ObjectiveText
							end
						end
					end
					net.Start("SendPlayerQuestInfo")
					net.WriteTable(QuestInfo)
					net.Send(pl)
					net.Start("SendPlayerQuest")
					net.WriteTable(AllQuests)
					net.WriteBit(0)
					net.Send(pl)
					return true
				end
			end
		end
	end
end

hook.Add("PlayerFootstep", "BearFootsteps", function(ply)
	if(ply.Bear != nil)then
		return true
	end
end)

if CLIENT then
	net.Receive( "SendBear", function()
		print([[Palms are sweaty
Knees weak, arms are heavy
Vomit on my sweater already
Mom’s spaghetti]])
		local tbl = net.ReadTable()
		local bear = ents.FindByName("123"..ents.GetByIndex(tbl[1]):GetName().."bearqwe")
		ents.GetByIndex(tbl[1]).Bear = bear
		ents.GetByIndex(tbl[1]).Bear.Follow = ents.GetByIndex(tbl[1])
		print(ents.GetByIndex(tbl[1]).Bear == bear)
	end)
end

net.Receive( "RetrievePlayerInventory", function(len, ply)
	local gear = nil
	local spells = nil
	local classes = nil
	local currency = nil
	local presets = nil
	if(!file.Exists("rpgdm/playerdata/"..ply:SteamID64().."/currency.txt", "DATA"))then
		print("DATA FILES FOR: ("..ply:GetName().."; "..ply:SteamID64()..") NOT FOUND")
		file.CreateDir( "rpgdm/playerdata/"..ply:SteamID64().."" )
		file.Write("rpgdm/playerdata/"..ply:SteamID64().."/spells.txt", util.TableToJSON(DefaultOwnedSpells))
		file.Write("rpgdm/playerdata/"..ply:SteamID64().."/gear.txt", util.TableToJSON(DefaultGear))
		file.Write("rpgdm/playerdata/"..ply:SteamID64().."/classes.txt", util.TableToJSON(DefaultClasses))
		file.Write("rpgdm/playerdata/"..ply:SteamID64().."/currency.txt", util.TableToJSON(DefaultCurrency))
		file.Write("rpgdm/playerdata/"..ply:SteamID64().."/presets.txt", util.TableToJSON(DefaultPresets))
		file.Write("rpgdm/playerdata/"..ply:SteamID64().."/options.txt", util.TableToJSON(DefaultOptions))
		file.Write("rpgdm/playerdata/"..ply:SteamID64().."/activequests.txt", util.TableToJSON({}))
		file.Write("rpgdm/playerdata/"..ply:SteamID64().."/completedquests.txt", util.TableToJSON({}))
	end
	gear = file.Read("rpgdm/playerdata/"..ply:SteamID64().."/gear.txt", "DATA")
	spells = file.Read("rpgdm/playerdata/"..ply:SteamID64().."/spells.txt", "DATA")
	classes = file.Read("rpgdm/playerdata/"..ply:SteamID64().."/classes.txt", "DATA")
	currency = file.Read("rpgdm/playerdata/"..ply:SteamID64().."/currency.txt", "DATA")
	presets = file.Read("rpgdm/playerdata/"..ply:SteamID64().."/presets.txt", "DATA")
	options = file.Read("rpgdm/playerdata/"..ply:SteamID64().."/options.txt", "DATA")
	
	local AllPlayerData = {gear, spells, classes, currency, presets, options}
	net.Start("SendPlayerInventory")
	net.WriteTable(AllPlayerData)
	net.Send(ply)
end)

net.Receive( "RetrievePlayerInventory2", function(len, ply)
	local gear = nil
	local spells = nil
	local classes = nil
	local currency = nil
	local presets = nil
	if(!file.Exists("rpgdm/playerdata/"..ply:SteamID64().."/currency.txt", "DATA"))then
		print("DATA FILES FOR: ("..ply:GetName().."; "..ply:SteamID64()..") NOT FOUND")
		file.CreateDir( "rpgdm/playerdata/"..ply:SteamID64().."" )
		file.Write("rpgdm/playerdata/"..ply:SteamID64().."/spells.txt", util.TableToJSON(DefaultOwnedSpells))
		file.Write("rpgdm/playerdata/"..ply:SteamID64().."/gear.txt", util.TableToJSON(DefaultGear))
		file.Write("rpgdm/playerdata/"..ply:SteamID64().."/classes.txt", util.TableToJSON(DefaultClasses))
		file.Write("rpgdm/playerdata/"..ply:SteamID64().."/currency.txt", util.TableToJSON(DefaultCurrency))
		file.Write("rpgdm/playerdata/"..ply:SteamID64().."/presets.txt", util.TableToJSON(DefaultPresets))
		file.Write("rpgdm/playerdata/"..ply:SteamID64().."/options.txt", util.TableToJSON(DefaultOptions))
	end
	gear = file.Read("rpgdm/playerdata/"..ply:SteamID64().."/gear.txt", "DATA")
	spells = file.Read("rpgdm/playerdata/"..ply:SteamID64().."/spells.txt", "DATA")
	classes = file.Read("rpgdm/playerdata/"..ply:SteamID64().."/classes.txt", "DATA")
	currency = file.Read("rpgdm/playerdata/"..ply:SteamID64().."/currency.txt", "DATA")
	presets = file.Read("rpgdm/playerdata/"..ply:SteamID64().."/presets.txt", "DATA")
	options = file.Read("rpgdm/playerdata/"..ply:SteamID64().."/options.txt", "DATA")
	
	local AllPlayerData = {gear, spells, classes, currency, presets, options}
	net.Start("SendPlayerInventory2")
	net.WriteTable(AllPlayerData)
	net.Send(ply)
end)

net.Receive( "ChooseSpellUpgrade", function(len, ply)
	local tbl = net.ReadTable()
	
	local presetIndex = tbl[1]
	local slot = tbl[2]
	local newspell = tbl[3]
	local presets = util.JSONToTable(file.Read("rpgdm/playerdata/"..ply:SteamID64().."/presets.txt", "DATA"))
	local upgrades = presets[presetIndex][5]
	local spells = presets[presetIndex][3]
	
	spells[slot] = newspell
	table.remove(upgrades, 1)
	
	print(ply.CurrentPreset)
	print(presets[presetIndex][1])
	
	if(ply.PresetName == presets[presetIndex][1])then
		SetSpells(ply, spells)
	end
	
	file.Write("rpgdm/playerdata/"..ply:SteamID64().."/presets.txt", util.TableToJSON(presets))
	ChatManager:SendToClient({Color( 100, 100, 255 ), "You have upgraded to ", Color( 100, 255, 100 ), GetSpellNameByID(newspell), Color( 100, 100, 255 ), "!"}, ply)
	ply:EmitSound("devin/blackbetty/weapons/levelup.wav", 150, 100+math.random(-10,10))
	ParticleEffect( "impact_light_heal", ply:GetPos() + Vector(0, 0, 48), Angle(0,0,0), ply )
end)

concommand.Add( "rpgdm_givequest", function(ply, command, args)
	if(args[1] == nil or args[1] == "")then
		print("Please specify a valid QuestID.")
		return false
	end
	if CLIENT then
		net.Start("SendQuest")
		net.WriteTable({LocalPlayer(), args})
		net.SendToServer()
	else
		SetPlayerOnQuest(ply, args[1])
	end
end)

net.Receive("SendQuest", function(len, ply)
	local qtable = net.ReadTable()
	SetPlayerOnQuest(qtable[1], qtable[2])
end)


concommand.Add( "rpgdm_clearallquests", function(ply, command, args)
	ClearAllQuests(ply)
end)

concommand.Add( "rpgdm_disttarget", GetDistanceToTarget )
concommand.Add( "rpgdm_setfaction", SetFaction )
concommand.Add( "rpgdm_settargetfaction", SetTargetFaction )
concommand.Add( "rpgdm_setclass", SetClass )
concommand.Add( "rpgdm_settargetme", SetTargetMe )
concommand.Add( "rpgdm_interactible", function(ply, command, args)
	local pos = ply:GetShootPos()
	local ang = ply:GetAimVector()
	
	local tracedata = {}
		tracedata.start = pos
		tracedata.endpos = pos+(ang*8000)
		tracedata.filter = ply
	local trace = util.TraceLine(tracedata)
	
	if trace.HitWorld then
		if SERVER then
			CreateInteractible(trace.HitPos)
		else
			-- net.Start("CreateNPC")
			-- net.WriteFloat(MobID)
			-- net.WriteVector(trace.HitPos)
			-- net.SendToServer()
		end
	end
end)

concommand.Add( "rpgdm_npc_create", function(ply, command, args) 
	local MobID = tonumber(args[1]) 
	local pos = ply:GetShootPos()
	local ang = ply:GetAimVector()
	
	local tracedata = {}
		tracedata.start = pos
		tracedata.endpos = pos+(ang*8000)
		tracedata.filter = ply
	local trace = util.TraceLine(tracedata)
	
	if trace.Hit then
		if SERVER then
			CreateNPC(MobID, trace.HitPos)
		else
			net.Start("CreateNPC")
			net.WriteFloat(MobID)
			net.WriteVector(trace.HitPos)
			net.SendToServer()
		end
	end
end)

	